home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / basics / kbexpl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  12.1 KB  |  431 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /** header ******************************************************************/
  18.  
  19. /*
  20.  * $Source$
  21.  * $Revision$
  22.  * $Date$
  23.  * $Author$
  24.  *
  25.  * creator: Brett Bainter
  26.  *
  27.  * purpose:
  28.  *    mixed model program demonstrating
  29.  *    ...how to get continuous pointer motion events for a gl widget.
  30.  *    ...how to get keyboard events for a gl widget in a widget heirarchy.
  31.  *    ...how to map most keyboard keys to an appropriate string rep.
  32.  *
  33.  * compiling:
  34.  *    cc -float -prototypes -O kbexpl.c -o kbexpl \
  35.  *    -s -lXirisw -lXm_s -lXt_s -lgl_s -lX11_s -lm -lc_s -lPW
  36.  *
  37.  * operating:
  38.  *    This program follows the correct motif style guide by forcing the
  39.  *    user to click in the gl widget with the left mouse button for it
  40.  *    to get keyboard focus.  Tab keys will be lost though as motif uses
  41.  *    these to move from tab group to tab group.
  42.  *
  43.  */
  44.  
  45. /** notes *******************************************************************/
  46. /** includes ****************************************************************/
  47.  
  48. #include <stdio.h>            /* standard */
  49. #include <Xm/Xm.h>            /* for motif */
  50. #include <Xm/Form.h>            /* motif widget */
  51. #include <Xm/Frame.h>            /* motif widget */
  52. #include <Xm/PushB.h>            /* motif widget */
  53. #include <Xm/RowColumn.h>        /* motif widget */
  54. #include <Xm/Separator.h>        /* motif widget */
  55. #include <X11/Xirisw/GlxMDraw.h>    /* gl widget */
  56.  
  57. /** defines *****************************************************************/
  58.  
  59. /* c environment */
  60. #define global
  61.  
  62. /* colors */
  63. #define RGB_BLACK    0x00000000
  64. #define RGB_RED        0x000000FF
  65. #define RGB_GREEN    0x0000FF00
  66. #define RGB_BLUE    0x00FF0000
  67.  
  68. /** typedefs ****************************************************************/
  69. /** prototypes **************************************************************/
  70.  
  71. extern void main(int argc, char *argv[], char *envp[]);
  72.  
  73. /* setup */
  74. static void install_colormaps(Widget top_level, Widget glw);
  75.  
  76. /* mixed model support */
  77. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data);
  78. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data);
  79. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data);
  80. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data);
  81.  
  82. /* callbacks (misc) */
  83. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data);
  84.  
  85. /* etc */
  86. static void draw_frame(Bool do_clear, Bool do_swap);
  87. static void xbutton_print(XEvent *event);
  88. static char *keycode_to_string(XEvent *event);
  89.  
  90. /** variables ***************************************************************/
  91.  
  92. /*
  93.  * mixed-model configuration:
  94.  */
  95. static GLXconfig glx_config[] = {
  96.     {GLX_NORMAL, GLX_DOUBLE, TRUE},
  97.     {GLX_NORMAL, GLX_RGB, TRUE},
  98.     {GLX_NORMAL, GLX_ZSIZE, GLX_NOCONFIG},
  99.     { 0, 0, 0 },
  100. };
  101.  
  102. /** functions ***************************************************************/
  103.  
  104. /*
  105.  * main - program entry point.
  106.  */
  107. global void main(
  108.     int argc,            /* argument count */
  109.     char *argv[],        /* argument vector */
  110.     char *envp[]        /* environment pointer */
  111. )
  112. {
  113.     XtAppContext app_context;    /* application context */
  114.     Display *dsp;        /* display ref */
  115.     Widget app_shell;        /* first widget */
  116.     Widget form;        /* surrounds app */
  117.     Widget rowcol;        /* manages input buttons */
  118.     Widget button;        /* quit button */
  119.     Widget separator;        /* between input and output */
  120.     Widget frame;        /* to surround gl widget */
  121.     Widget glw;            /* the gl widget inside window */
  122.     Arg args[15];        /* for name/value pairs */
  123.     int n;            /* for reusable indices */
  124.  
  125.     /* initialize toolkit, creating application shell */
  126.     n = 0;
  127.     XtSetArg(args[n], XmNtitle, "KB Echo"); n++;
  128.     app_shell = XtAppInitialize(
  129.     &app_context, "Kbecho", NULL, 0, &argc, argv, NULL, args, n
  130.     );
  131.  
  132.     /* create container for app */
  133.     n = 0;
  134.     form = XmCreateForm(app_shell, "form", args, n);
  135.     XtManageChild(form);
  136.  
  137.     /* create the command area */
  138.     n = 0;
  139.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  140.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  141.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  142.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  143.     rowcol = XmCreateRowColumn(form, "rowcol", args, n);
  144.     XtManageChild(rowcol);
  145.  
  146.     /* create the command area buttons */
  147.     n = 0;
  148.     button = XmCreatePushButton(rowcol, "Quit", args, n);
  149.     XtAddCallback(button, XmNactivateCallback, cb_quit, NULL);
  150.     XtManageChild(button);
  151.  
  152.     /* create separator between command area and output area */
  153.     n = 0;
  154.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  155.     XtSetArg(args[n], XmNleftWidget, rowcol); n++;
  156.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  157.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  158.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  159.     separator = XmCreateSeparator(form, "separator", args, n);
  160.     XtManageChild(separator);
  161.  
  162.     /* create the output area */
  163.     /* create the frame */
  164.     n = 0;
  165.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  166.     XtSetArg(args[n], XmNleftWidget, separator); n++;
  167.     XtSetArg(args[n], XmNleftOffset, 5); n++;
  168.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  169.     XtSetArg(args[n], XmNrightOffset, 5); n++;
  170.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  171.     XtSetArg(args[n], XmNbottomOffset, 5); n++;
  172.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  173.     XtSetArg(args[n], XmNtopOffset, 5); n++;
  174.     XtSetArg(args[n], XmNshadowThickness, 6); n++;
  175.     frame = XmCreateFrame(form, "frame", args, n);
  176.     XtManageChild(frame);
  177.  
  178.     /* create the gl widget */
  179.     n = 0;
  180.     XtSetArg(args[n], GlxNglxConfig, glx_config); n++;
  181.     XtSetArg(args[n], XmNtraversalOn, True); n++;
  182.     XtSetArg(args[n], XmNborderWidth, 0); n++;
  183.     XtSetArg(args[n], XmNwidth, 400); n++;
  184.     XtSetArg(args[n], XmNheight, 400); n++;
  185.     glw = GlxCreateMDraw(frame, "glw", args, n);
  186.     XtManageChild(glw);
  187.     XtAddCallback(glw, GlxNexposeCallback, cb_gl_expose, 0);
  188.     XtAddCallback(glw, GlxNresizeCallback, cb_gl_resize, 0);
  189.     XtAddCallback(glw, GlxNginitCallback, cb_gl_ginit, 0);
  190.     XtAddCallback(glw, GlxNinputCallback, cb_gl_input, 0);
  191.  
  192.     /* realize the app, creating the actual x windows */
  193.     XtRealizeWidget(app_shell);
  194.     install_colormaps(app_shell, glw);
  195.  
  196.     /* enter the event loop */
  197.     XtAppMainLoop(app_context);
  198. }
  199.  
  200.  
  201. /*- support: setup ---------------------------------------------------------*/
  202. /*
  203.  * install_colormaps - let the window manager know about our colormaps.
  204.  */
  205. static void install_colormaps(Widget top_level, Widget glw)
  206. {
  207.     Window overlay_win, popup_win, underlay_win;
  208.     Window window[5];
  209.     int i;
  210.  
  211.     XtVaGetValues(
  212.     glw,
  213.     GlxNoverlayWindow, &overlay_win,
  214.     GlxNpopupWindow, &popup_win,
  215.     GlxNunderlayWindow, &underlay_win,
  216.     NULL
  217.     );
  218.     i = 0;
  219.     if (overlay_win)
  220.     window[i++] = overlay_win;
  221.     if (popup_win)
  222.     window[i++] = popup_win;
  223.     if (underlay_win)
  224.     window[i++] = underlay_win;
  225.     window[i++] = XtWindow(glw);
  226.     window[i++] = XtWindow(top_level);
  227.     XSetWMColormapWindows(XtDisplay(top_level), XtWindow(top_level), window, i);
  228. }
  229.  
  230.  
  231. /*- support: callbacks (gl widget) -----------------------------------------*/
  232. /*
  233.  * cb_gl_expose - handle expose events for the gl widget.
  234.  */
  235. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data)
  236. {
  237.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  238.  
  239.     printf("cb_gl_expose()\n");
  240.     GLXwinset(XtDisplay(w), XtWindow(w));
  241.     draw_frame(TRUE, TRUE);
  242. }
  243.  
  244.  
  245. /*
  246.  * cb_gl_resize - handle resize events for the gl widget.
  247.  */
  248. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data)
  249. {
  250.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  251.  
  252.     printf("cb_gl_resize()\n");
  253.     GLXwinset(XtDisplay(w), XtWindow(w));
  254.     viewport(0, glx->width-1, 0, glx->height-1);
  255. }
  256.  
  257.  
  258. /*
  259.  * cb_gl_ginit - perform any necessary graphics initialization.
  260.  */
  261. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data)
  262. {
  263.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  264.  
  265.     printf("cb_gl_ginit()\n");
  266.     GLXwinset(XtDisplay(w), XtWindow(w));
  267.  
  268.     /* add pointer motion events and enter/leave events */
  269.     XSelectInput(
  270.     XtDisplay(w), XtWindow(w), XtBuildEventMask(w) | PointerMotionMask
  271.     );
  272.     XtAugmentTranslations(
  273.     w, XtParseTranslationTable("<MotionNotify>: glxInput()")
  274.     );
  275.  
  276.     mmode(MVIEWING);
  277.     ortho2(0.0, 100.0, 0.0, 100.0);
  278.     gflush();
  279. }
  280.  
  281.  
  282. /*
  283.  * cb_gl_input - handle input from a gl window.
  284.  */
  285. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data)
  286. {
  287.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  288.     XEvent *event;
  289.  
  290.     GLXwinset(XtDisplay(w), XtWindow(w));
  291.     printf("cb_gl_input( ");
  292.     event = glx->event;
  293.     switch (event->type) {
  294.     case ButtonPress:
  295.     printf("ButtonPress  (");
  296.     xbutton_print(event);
  297.     printf(")");
  298.     if (event->xbutton.button == Button1) {
  299.         printf("XmProcessTraversal(w, XmTRAVERSE_CURRENT)\n");
  300.         XmProcessTraversal(w, XmTRAVERSE_CURRENT);
  301.     }
  302.     break;
  303.     case ButtonRelease:
  304.     printf("ButtonRelease(");
  305.     xbutton_print(event);
  306.     printf(")");
  307.     break;
  308.     case KeyPress:
  309.     printf("KeyPress  (%s)", keycode_to_string(event));
  310.     break;
  311.     case KeyRelease:
  312.     printf("KeyRelease(%s)", keycode_to_string(event));
  313.     break;
  314.     case MotionNotify:
  315.     printf("MotionNotify(%d, %d)", event->xmotion.x, event->xmotion.y);
  316.     break;
  317.     default:
  318.     printf("UnknownEventType(%d)", event->type);
  319.     break;
  320.     }
  321.     printf(" )\n");
  322. }
  323.  
  324.  
  325. /*- support: callbacks (misc) ----------------------------------------------*/
  326. /*
  327.  * cb_quit - exit application.
  328.  */
  329. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data)
  330. {
  331.     exit(0);
  332. }
  333.  
  334.  
  335. /*- support: drawing -------------------------------------------------------*/
  336. /*
  337.  * draw_frame -
  338.  */
  339. static void draw_frame(Bool do_clear, Bool do_swap)
  340. {
  341.     static float vert[][2] = {    /* a box */
  342.     { 0.0,  0.0},
  343.     {20.0,  0.0},
  344.     {20.0, 20.0},
  345.     { 0.0, 20.0},
  346.     };
  347.  
  348.     if (do_clear) {
  349.     cpack(RGB_BLACK);
  350.     clear();
  351.     }
  352.  
  353.     pushmatrix();
  354.     translate(15.0, 40.0, 0.0);
  355.     cpack(RGB_RED);
  356.     bgnpolygon();
  357.     v2f(vert[0]);
  358.     v2f(vert[1]);
  359.     v2f(vert[2]);
  360.     v2f(vert[3]);
  361.     endpolygon();
  362.     translate(25.0, 0.0, 0.0);
  363.     cpack(RGB_GREEN);
  364.     bgnpolygon();
  365.     v2f(vert[0]);
  366.     v2f(vert[1]);
  367.     v2f(vert[2]);
  368.     v2f(vert[3]);
  369.     endpolygon();
  370.     translate(25.0, 0.0, 0.0);
  371.     cpack(RGB_BLUE);
  372.     bgnpolygon();
  373.     v2f(vert[0]);
  374.     v2f(vert[1]);
  375.     v2f(vert[2]);
  376.     v2f(vert[3]);
  377.     endpolygon();
  378.     popmatrix();
  379.  
  380.     if (do_swap) {
  381.     swapbuffers();
  382.     gflush();
  383.     }
  384. }
  385.  
  386.  
  387. /*- support: echoing keys/buttons ------------------------------------------*/
  388. /*
  389.  * xbutton_print -
  390.  */
  391. static void xbutton_print(XEvent *event)
  392. {
  393.     char *str;
  394.  
  395.     switch (event->xbutton.button) {
  396.     case Button1: str = "Button1"; break;
  397.     case Button2: str = "Button2"; break;
  398.     case Button3: str = "Button3"; break;
  399.     case Button4: str = "Button4"; break;
  400.     case Button5: str = "Button5"; break;
  401.     default:      str = "Button?"; break;
  402.     }
  403.     printf("%s", str);
  404. }
  405.  
  406.  
  407. /*
  408.  * keycode_to_string -
  409.  */
  410. static char *keycode_to_string(XEvent *event)
  411. {
  412.     #define KEYSTR_SIZE    100
  413.     static char keystr[KEYSTR_SIZE+1];
  414.     /**/
  415.     KeySym keysym;
  416.     int count;
  417.     char *tmp;
  418.  
  419.     count = XLookupString(
  420.     (XKeyEvent *) event, keystr, KEYSTR_SIZE, &keysym, NULL
  421.     );
  422.     keystr[count] = '\0';
  423.     if (count == 0) {
  424.     tmp = XKeysymToString(keysym);
  425.     strcpy(keystr, tmp!=NULL? tmp : "");
  426.     }
  427.     return (keystr);
  428. }
  429.  
  430. /** eof *********************************************************************/
  431.